# include <intrin.h>
#endif
+/*
+ * @GTK_CSS_SELECTOR_CATEGORY_SIMPLE: A simple selector
+ * @GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL: A simple selector that matches
+ * what change tracking considers a "radical change"
+ * @GTK_CSS_SELECTOR_SIBLING: A selector matching siblings
+ * @GTK_CSS_SELECTOR_CATEGORY_PARENT: A selector matching a parent or other
+ * ancestor
+ *
+ * Categorize the selectors. This helps in various loops when matching.
+ */
+typedef enum {
+ GTK_CSS_SELECTOR_CATEGORY_SIMPLE,
+ GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL,
+ GTK_CSS_SELECTOR_CATEGORY_PARENT,
+ GTK_CSS_SELECTOR_CATEGORY_SIBLING,
+} GtkCssSelectorCategory;
+
typedef struct _GtkCssSelectorClass GtkCssSelectorClass;
typedef gboolean (* GtkCssSelectorForeachFunc) (const GtkCssSelector *selector,
const GtkCssMatcher *matcher,
struct _GtkCssSelectorClass {
const char *name;
+ GtkCssSelectorCategory category;
void (* print) (const GtkCssSelector *selector,
GString *string);
guint (* hash_one) (const GtkCssSelector *selector);
int (* compare_one) (const GtkCssSelector *a,
const GtkCssSelector *b);
-
- guint is_simple : 1;
- guint ignore_for_change : 1;
};
typedef enum {
static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
"descendant",
+ GTK_CSS_SELECTOR_CATEGORY_PARENT,
gtk_css_selector_descendant_print,
gtk_css_selector_descendant_foreach_matcher,
gtk_css_selector_default_match_one,
gtk_css_selector_default_add_specificity,
gtk_css_selector_default_hash_one,
gtk_css_selector_default_compare_one,
- FALSE,
- TRUE
};
/* CHILD */
static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
"child",
+ GTK_CSS_SELECTOR_CATEGORY_PARENT,
gtk_css_selector_child_print,
gtk_css_selector_child_foreach_matcher,
gtk_css_selector_default_match_one,
gtk_css_selector_default_add_specificity,
gtk_css_selector_default_hash_one,
gtk_css_selector_default_compare_one,
- FALSE,
- TRUE
};
/* SIBLING */
static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = {
"sibling",
+ GTK_CSS_SELECTOR_CATEGORY_SIBLING,
gtk_css_selector_sibling_print,
gtk_css_selector_sibling_foreach_matcher,
gtk_css_selector_default_match_one,
gtk_css_selector_default_add_specificity,
gtk_css_selector_default_hash_one,
gtk_css_selector_default_compare_one,
- FALSE,
- TRUE
};
/* ADJACENT */
static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
"adjacent",
+ GTK_CSS_SELECTOR_CATEGORY_SIBLING,
gtk_css_selector_adjacent_print,
gtk_css_selector_adjacent_foreach_matcher,
gtk_css_selector_default_match_one,
gtk_css_selector_default_add_specificity,
gtk_css_selector_default_hash_one,
gtk_css_selector_default_compare_one,
- FALSE,
- TRUE
};
/* SIMPLE SELECTOR DEFINE */
\
static const GtkCssSelectorClass GTK_CSS_SELECTOR_ ## c = { \
G_STRINGIFY(n), \
+ ignore_for_change ? GTK_CSS_SELECTOR_CATEGORY_SIMPLE : GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL, \
gtk_css_selector_ ## n ## _print, \
gtk_css_selector_default_foreach_matcher, \
match_func, \
gtk_css_selector_ ## n ## _add_specificity, \
hash_func, \
comp_func, \
- TRUE, \
- ignore_for_change \
};\
\
static const GtkCssSelectorClass GTK_CSS_SELECTOR_NOT_ ## c = { \
"not_" G_STRINGIFY(n), \
+ ignore_for_change ? GTK_CSS_SELECTOR_CATEGORY_SIMPLE : GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL, \
gtk_css_selector_not_ ## n ## _print, \
gtk_css_selector_default_foreach_matcher, \
gtk_css_selector_not_ ## n ## _match_one, \
gtk_css_selector_ ## n ## _add_specificity, \
hash_func, \
comp_func, \
- TRUE, \
- ignore_for_change \
};
/* ANY */
/******************** SelectorTree handling *****************/
+static gboolean
+gtk_css_selector_is_simple (const GtkCssSelector *selector)
+{
+ switch (selector->class->category)
+ {
+ case GTK_CSS_SELECTOR_CATEGORY_SIMPLE:
+ case GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL:
+ return TRUE;
+ case GTK_CSS_SELECTOR_CATEGORY_PARENT:
+ case GTK_CSS_SELECTOR_CATEGORY_SIBLING:
+ return FALSE;
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
+}
+
static GHashTable *
gtk_css_selectors_count_initial_init (void)
{
static void
gtk_css_selectors_count_initial (const GtkCssSelector *selector, GHashTable *hash_one)
{
- if (!selector->class->is_simple)
+ if (!gtk_css_selector_is_simple (selector))
{
guint count = GPOINTER_TO_INT (g_hash_table_lookup (hash_one, selector));
g_hash_table_replace (hash_one, (gpointer)selector, GUINT_TO_POINTER (count + 1));
}
for (;
- selector && selector->class->is_simple;
+ selector && gtk_css_selector_is_simple (selector);
selector = gtk_css_selector_previous (selector))
{
guint count = GPOINTER_TO_INT (g_hash_table_lookup (hash_one, selector));
static gboolean
gtk_css_selectors_has_initial_selector (const GtkCssSelector *selector, const GtkCssSelector *initial)
{
- if (!selector->class->is_simple)
+ if (!gtk_css_selector_is_simple (selector))
return gtk_css_selector_equal (selector, initial);
for (;
- selector && selector->class->is_simple;
+ selector && gtk_css_selector_is_simple (selector);
selector = gtk_css_selector_previous (selector))
{
if (gtk_css_selector_equal (selector, initial))
without losing any other selectors */
if (!gtk_css_selector_equal (selector, initial))
{
- for (found = selector; found && found->class->is_simple; found = (GtkCssSelector *)gtk_css_selector_previous (found))
+ for (found = selector; found && gtk_css_selector_is_simple (found); found = (GtkCssSelector *)gtk_css_selector_previous (found))
{
if (gtk_css_selector_equal (found, initial))
break;
}
- g_assert (found != NULL && found->class->is_simple);
+ g_assert (found != NULL && gtk_css_selector_is_simple (found));
tmp = *found;
*found = *selector;
gtk_css_selector_match_for_change (const GtkCssSelector *selector,
const GtkCssMatcher *matcher)
{
- if (selector->class->ignore_for_change)
+ if (selector->class->category != GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL)
return TRUE;
return selector->class->match_one (selector, matcher);
if (!gtk_css_selector_match_for_change (&tree->selector, matcher))
return 0;
- if (!tree->selector.class->is_simple)
+ if (!gtk_css_selector_is_simple (&tree->selector))
return gtk_css_selector_tree_collect_change (tree) | GTK_CSS_CHANGE_GOT_MATCH;
for (prev = gtk_css_selector_tree_get_previous (tree);
/* print name and * selector before others */
for (iter = tree;
- iter && iter->selector.class->is_simple;
+ iter && gtk_css_selector_is_simple (&iter->selector);
iter = gtk_css_selector_tree_get_parent (iter))
{
if (iter->selector.class == >K_CSS_SELECTOR_NAME ||
}
/* now print other simple selectors */
for (iter = tree;
- iter && iter->selector.class->is_simple;
+ iter && gtk_css_selector_is_simple (&iter->selector);
iter = gtk_css_selector_tree_get_parent (iter))
{
if (iter->selector.class != >K_CSS_SELECTOR_NAME &&